package entity

import (
	. "data/datatype"
	"errors"
)

type Player struct {
	ObjectType int
	BaseObj

	hp    int8    //血量
	mp    int16   //魔法量
	addhp int16   //增加魔法量
	addmp int16   //增加魔法量
	pos   Vector3 //位置坐标

	//表格定义
	friend_r PlayerFriend //好友表
	task_r   PlayerTask   //任务表
}

//获取类型
func (obj *Player) Type(p string) (int, string, error) {
	switch p {

	case "Hp":
		return DT_INT8, "int8", nil

	case "Mp":
		return DT_INT16, "int16", nil

	case "AddHp":
		return DT_INT16, "int16", nil

	case "AddMp":
		return DT_INT16, "int16", nil

	case "Pos":
		return DT_VECTOR3, "Vector3", nil

	default:
		return obj.BaseObj.Type(p)
	}
}

//通过属性名设置值
func (obj *Player) Set(p string, v interface{}) error {
	switch p {

	case "Hp":
		val, ok := v.(int8)
		if ok {
			obj.SetHp(val)
		} else {
			return errors.New("Set(Hp) value type mismatch")
		}

	case "Mp":
		val, ok := v.(int16)
		if ok {
			obj.SetMp(val)
		} else {
			return errors.New("Set(Mp) value type mismatch")
		}

	case "AddHp":
		val, ok := v.(int16)
		if ok {
			obj.SetAddHp(val)
		} else {
			return errors.New("Set(AddHp) value type mismatch")
		}

	case "AddMp":
		val, ok := v.(int16)
		if ok {
			obj.SetAddMp(val)
		} else {
			return errors.New("Set(AddMp) value type mismatch")
		}

	case "Pos":
		val, ok := v.(Vector3)
		if ok {
			obj.SetPos(val)
		} else {
			return errors.New("Set(Pos) value type mismatch")
		}

	default:
		obj.BaseObj.Set(p, v)
	}

	return nil
}

//通过属性名获取值
func (obj *Player) Get(p string) (val interface{}, err error) {
	switch p {

	case "Hp":
		return obj.hp, nil

	case "Mp":
		return obj.mp, nil

	case "AddHp":
		return obj.addhp, nil

	case "AddMp":
		return obj.addmp, nil

	case "Pos":
		return obj.pos, nil

	default:
		return obj.BaseObj.Get(p)
	}
}

//是否需要同步到其它客户端
func (obj *Player) IsPublic(p string) bool {
	switch p {

	case "Hp":
		return true

	case "Mp":
		return true

	case "AddHp":
		return true

	case "AddMp":
		return true

	default:
		return obj.BaseObj.IsPublic(p)
	}
}

//是否需要同步到自己的客户端
func (obj *Player) IsPrivate(p string) bool {
	switch p {

	case "Hp":
		return true

	case "Mp":
		return true

	case "AddHp":
		return true

	case "AddMp":
		return true

	default:
		return obj.BaseObj.IsPrivate(p)
	}
}

//是否需要存档
func (obj *Player) IsSave(p string) bool {
	switch p {

	case "Hp":
		return true

	case "Mp":
		return true

	case "AddHp":
		return true

	case "AddMp":
		return true

	case "Pos":
		return true

	default:
		return obj.BaseObj.IsSave(p)
	}
}

//血量
func (obj *Player) SetHp(v int8) {
	obj.hp = v
	obj.setModify("Hp", v)
	obj.setDirty("Hp", v)
}

func (obj *Player) GetHp() int8 {
	return obj.hp
}

//魔法量
func (obj *Player) SetMp(v int16) {
	obj.mp = v
	obj.setModify("Mp", v)
	obj.setDirty("Mp", v)
}

func (obj *Player) GetMp() int16 {
	return obj.mp
}

//增加魔法量
func (obj *Player) SetAddHp(v int16) {
	obj.addhp = v
	obj.setModify("AddHp", v)
	obj.setDirty("AddHp", v)
}

func (obj *Player) GetAddHp() int16 {
	return obj.addhp
}

//增加魔法量
func (obj *Player) SetAddMp(v int16) {
	obj.addmp = v
	obj.setModify("AddMp", v)
	obj.setDirty("AddMp", v)
}

func (obj *Player) GetAddMp() int16 {
	return obj.addmp
}

//位置坐标
func (obj *Player) SetPos(v Vector3) {
	obj.pos = v
	obj.setDirty("Pos", v)
}

func (obj *Player) GetPos() Vector3 {
	return obj.pos
}

//PlayerFriend
type PlayerFriend struct {
	maxRows int
	cols    int
	rows    []PlayerFriendRow
	dirty   bool
}

//PlayerFriend行定义
type PlayerFriendRow struct {
	id   int32   //ID
	name string  //名称
	hp   int32   //血
	mp   int32   //魔
	sex  int8    //性别
	pos  Vector3 //坐标
}

//表格的容量
func (rec *PlayerFriend) Cap() int {
	return rec.maxRows
}

//表格当前的行数
func (rec *PlayerFriend) Rows() int {
	return len(rec.rows)
}

//获取列定义
func (rec *PlayerFriend) ColTypes() ([]int, []string) {
	col := []int{DT_INT32, DT_STRING, DT_INT32, DT_INT32, DT_INT8, DT_VECTOR3}
	cols := []string{"int32", "string", "int32", "int32", "int8", "Vector3"}
	return col, cols
}

//获取列数
func (rec *PlayerFriend) Cols() int {
	return rec.cols
}

//脏标志
func (rec *PlayerFriend) Dirty() bool {
	return rec.dirty
}

func (rec *PlayerFriend) ClearDirty() {
	rec.dirty = false
}

//通过行列设置值
func (rec *PlayerFriend) Set(row, col int, val interface{}) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	if col < 0 || col >= 6 {
		return errors.New("col error")
	}

	r := rec.rows[row]

	switch col {

	case 0:
		val, ok := val.(int32)
		if ok {
			r.id = val
		} else {
			return errors.New("val type mismatch")
		}

	case 1:
		val, ok := val.(string)
		if ok {
			r.name = val
		} else {
			return errors.New("val type mismatch")
		}

	case 2:
		val, ok := val.(int32)
		if ok {
			r.hp = val
		} else {
			return errors.New("val type mismatch")
		}

	case 3:
		val, ok := val.(int32)
		if ok {
			r.mp = val
		} else {
			return errors.New("val type mismatch")
		}

	case 4:
		val, ok := val.(int8)
		if ok {
			r.sex = val
		} else {
			return errors.New("val type mismatch")
		}

	case 5:
		val, ok := val.(Vector3)
		if ok {
			r.pos = val
		} else {
			return errors.New("val type mismatch")
		}

	}

	rec.dirty = true
	return nil
}

//通过行列获取值
func (rec *PlayerFriend) Get(row, col int) (val interface{}, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	if col < 0 || col >= 6 {
		err = errors.New("col error")
		return
	}

	r := rec.rows[row]

	switch col {

	case 0:
		val = r.id

	case 1:
		val = r.name

	case 2:
		val = r.hp

	case 3:
		val = r.mp

	case 4:
		val = r.sex

	case 5:
		val = r.pos

	}

	return
}

//设置ID
func (rec *PlayerFriend) SetId(row int, v int32) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].id = v
	rec.dirty = true
	return nil
}

//获取ID
func (rec *PlayerFriend) GetId(row int) (val int32, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].id
	return
}

//设置名称
func (rec *PlayerFriend) SetName(row int, v string) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].name = v
	rec.dirty = true
	return nil
}

//获取名称
func (rec *PlayerFriend) GetName(row int) (val string, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].name
	return
}

//设置血
func (rec *PlayerFriend) SetHp(row int, v int32) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].hp = v
	rec.dirty = true
	return nil
}

//获取血
func (rec *PlayerFriend) GetHp(row int) (val int32, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].hp
	return
}

//设置魔
func (rec *PlayerFriend) SetMp(row int, v int32) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].mp = v
	rec.dirty = true
	return nil
}

//获取魔
func (rec *PlayerFriend) GetMp(row int) (val int32, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].mp
	return
}

//设置性别
func (rec *PlayerFriend) SetSex(row int, v int8) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].sex = v
	rec.dirty = true
	return nil
}

//获取性别
func (rec *PlayerFriend) GetSex(row int) (val int8, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].sex
	return
}

//设置坐标
func (rec *PlayerFriend) SetPos(row int, v Vector3) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].pos = v
	rec.dirty = true
	return nil
}

//获取坐标
func (rec *PlayerFriend) GetPos(row int) (val Vector3, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].pos
	return
}

//增加一行,row=-1时,在表格最后面插入一行,否则在row处插入,返回-1插入失败,否则返回插入的行号
func (rec *PlayerFriend) Add(row int, id int32, name string, hp int32, mp int32, sex int8, pos Vector3) int {
	add := -1

	if len(rec.rows) >= rec.maxRows {
		return add
	}

	r := PlayerFriendRow{id, name, hp, mp, sex, pos}

	if row == -1 {
		rec.rows = append(rec.rows, r)
		add = len(rec.rows) - 1
	} else {
		if row >= 0 && row < len(rec.rows) {
			rec.rows = append(rec.rows, PlayerFriendRow{})
			copy(rec.rows[row+1:], rec.rows[row:])
			rec.rows[row] = r
			add = row
		} else {
			rec.rows = append(rec.rows, r)
			add = len(rec.rows) - 1
		}

	}
	if add != -1 {
		rec.dirty = true
	}
	return add
}

//获取数据
func (rec *PlayerFriend) Scan(row int, id *int32, name *string, hp *int32, mp *int32, sex *int8, pos *Vector3) bool {

	if row < 0 || row >= len(rec.rows) {
		return false
	}

	r := rec.rows[row]
	*id = r.id
	*name = r.name
	*hp = r.hp
	*mp = r.mp
	*sex = r.sex
	*pos = r.pos

	return true
}

//删除一行
func (rec *PlayerFriend) Del(row int) {
	if row >= 0 {
		if len(rec.rows) > 1 {
			if row == 0 {
				copy(rec.rows[:], rec.rows[1:])
			} else {
				copy(rec.rows[row:], rec.rows[row+1:])
			}
			rec.rows = rec.rows[:len(rec.rows)-1]
			rec.dirty = true
		} else {
			rec.Clear()
		}
	}
}

//清空表格
func (rec *PlayerFriend) Clear() {
	rec.rows = rec.rows[:0]
	rec.dirty = true
}

//初始化friend表
func (obj *Player) initPlayerFriend() {
	obj.friend_r.maxRows = 256
	obj.friend_r.cols = 6
	obj.friend_r.rows = make([]PlayerFriendRow, 0, 256)
}

//获取PlayerFriend表
func (obj *Player) GetPlayerFriend() *PlayerFriend {
	return &obj.friend_r
}

//PlayerTask
type PlayerTask struct {
	maxRows int
	cols    int
	rows    []PlayerTaskRow
	dirty   bool
}

//PlayerTask行定义
type PlayerTaskRow struct {
	id   int32   //ID
	name string  //名称
	desc string  //描述
	pos  Vector3 //坐标
}

//表格的容量
func (rec *PlayerTask) Cap() int {
	return rec.maxRows
}

//表格当前的行数
func (rec *PlayerTask) Rows() int {
	return len(rec.rows)
}

//获取列定义
func (rec *PlayerTask) ColTypes() ([]int, []string) {
	col := []int{DT_INT32, DT_STRING, DT_STRING, DT_VECTOR3}
	cols := []string{"int32", "string", "string", "Vector3"}
	return col, cols
}

//获取列数
func (rec *PlayerTask) Cols() int {
	return rec.cols
}

//脏标志
func (rec *PlayerTask) Dirty() bool {
	return rec.dirty
}

func (rec *PlayerTask) ClearDirty() {
	rec.dirty = false
}

//通过行列设置值
func (rec *PlayerTask) Set(row, col int, val interface{}) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	if col < 0 || col >= 4 {
		return errors.New("col error")
	}

	r := rec.rows[row]

	switch col {

	case 0:
		val, ok := val.(int32)
		if ok {
			r.id = val
		} else {
			return errors.New("val type mismatch")
		}

	case 1:
		val, ok := val.(string)
		if ok {
			r.name = val
		} else {
			return errors.New("val type mismatch")
		}

	case 2:
		val, ok := val.(string)
		if ok {
			r.desc = val
		} else {
			return errors.New("val type mismatch")
		}

	case 3:
		val, ok := val.(Vector3)
		if ok {
			r.pos = val
		} else {
			return errors.New("val type mismatch")
		}

	}

	rec.dirty = true
	return nil
}

//通过行列获取值
func (rec *PlayerTask) Get(row, col int) (val interface{}, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	if col < 0 || col >= 4 {
		err = errors.New("col error")
		return
	}

	r := rec.rows[row]

	switch col {

	case 0:
		val = r.id

	case 1:
		val = r.name

	case 2:
		val = r.desc

	case 3:
		val = r.pos

	}

	return
}

//设置ID
func (rec *PlayerTask) SetId(row int, v int32) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].id = v
	rec.dirty = true
	return nil
}

//获取ID
func (rec *PlayerTask) GetId(row int) (val int32, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].id
	return
}

//设置名称
func (rec *PlayerTask) SetName(row int, v string) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].name = v
	rec.dirty = true
	return nil
}

//获取名称
func (rec *PlayerTask) GetName(row int) (val string, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].name
	return
}

//设置描述
func (rec *PlayerTask) SetDesc(row int, v string) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].desc = v
	rec.dirty = true
	return nil
}

//获取描述
func (rec *PlayerTask) GetDesc(row int) (val string, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].desc
	return
}

//设置坐标
func (rec *PlayerTask) SetPos(row int, v Vector3) error {
	if row < 0 || row >= len(rec.rows) {
		return errors.New("row error")
	}

	rec.rows[row].pos = v
	rec.dirty = true
	return nil
}

//获取坐标
func (rec *PlayerTask) GetPos(row int) (val Vector3, err error) {
	if row < 0 || row >= len(rec.rows) {
		err = errors.New("row error")
		return
	}

	val = rec.rows[row].pos
	return
}

//增加一行,row=-1时,在表格最后面插入一行,否则在row处插入,返回-1插入失败,否则返回插入的行号
func (rec *PlayerTask) Add(row int, id int32, name string, desc string, pos Vector3) int {
	add := -1

	if len(rec.rows) >= rec.maxRows {
		return add
	}

	r := PlayerTaskRow{id, name, desc, pos}

	if row == -1 {
		rec.rows = append(rec.rows, r)
		add = len(rec.rows) - 1
	} else {
		if row >= 0 && row < len(rec.rows) {
			rec.rows = append(rec.rows, PlayerTaskRow{})
			copy(rec.rows[row+1:], rec.rows[row:])
			rec.rows[row] = r
			add = row
		} else {
			rec.rows = append(rec.rows, r)
			add = len(rec.rows) - 1
		}

	}
	if add != -1 {
		rec.dirty = true
	}
	return add
}

//获取数据
func (rec *PlayerTask) Scan(row int, id *int32, name *string, desc *string, pos *Vector3) bool {

	if row < 0 || row >= len(rec.rows) {
		return false
	}

	r := rec.rows[row]
	*id = r.id
	*name = r.name
	*desc = r.desc
	*pos = r.pos

	return true
}

//删除一行
func (rec *PlayerTask) Del(row int) {
	if row >= 0 {
		if len(rec.rows) > 1 {
			if row == 0 {
				copy(rec.rows[:], rec.rows[1:])
			} else {
				copy(rec.rows[row:], rec.rows[row+1:])
			}
			rec.rows = rec.rows[:len(rec.rows)-1]
			rec.dirty = true
		} else {
			rec.Clear()
		}
	}
}

//清空表格
func (rec *PlayerTask) Clear() {
	rec.rows = rec.rows[:0]
	rec.dirty = true
}

//初始化task表
func (obj *Player) initPlayerTask() {
	obj.task_r.maxRows = 256
	obj.task_r.cols = 4
	obj.task_r.rows = make([]PlayerTaskRow, 0, 256)
}

//获取PlayerTask表
func (obj *Player) GetPlayerTask() *PlayerTask {
	return &obj.task_r
}

//初始化所有的表格
func (obj *Player) initRec() {
	obj.initPlayerFriend()
	obj.initPlayerTask()

}

//获取某个表格
func (obj *Player) GetRec(rec string) interface{} {
	switch rec {

	case "Friend":
		return &obj.friend_r

	case "Task":
		return &obj.task_r

	default:
		return obj.BaseObj.GetRec(rec)
	}
}

//由子类调用的初始化函数
func (obj *Player) baseInit(dirty, modify map[string]interface{}) {
	//初始化表格
	obj.initRec()

	//初始化基类
	obj.BaseObj.baseInit(dirty, modify)

}

//创建函数
func CreatePlayer() *Player {
	obj := &Player{}
	obj.ObjectType = PLAYER
	obj.initRec()
	obj.BaseObj.baseInit(make(map[string]interface{}), make(map[string]interface{}))
	return obj
}
